package pub.tbc.rubbish.client.util;

import com.google.common.collect.Lists;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import pub.tbc.rubbish.client.Constant;
import pub.tbc.toolkit.Objs;
import pub.tbc.toolkit.PropsUtil;
import pub.tbc.toolkit.classes.ClassScanner;
import pub.tbc.toolkit.classes.impl.DefaultClassScanner;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author tbc on 2016/12/6 11:55:38.
 */
public class ServiceHelper {
    private final String SERVICE_NAME_SEPARATOR = ".";
    private final String DEFAULT_BASIS_PACKAGE = "pub.tbc";

    private List<String> services = Lists.newArrayList();

    /**
     * 获取并设置本地服务列表：<br>
     * 1. 扫描基础包路径; <br>
     * 2. 判断类标注@Controller;<br>
     * 3. 判断方法标注@RequestMapping;<br>
     */
    public void setLocalService() {
        String basisPackage = PropsUtil.getString(PropsUtil.load(Constant.DEFAULT_CONFIG_FILE), Constant.BASIS_PACKAGE);
        if (Objs.isEmpty(basisPackage)) basisPackage = DEFAULT_BASIS_PACKAGE;

        ClassScanner scanner = new DefaultClassScanner();
        List<Class<?>> classes = scanner.getClassList(basisPackage);

        classes.stream()
                .filter(this::isServiceController)
                .forEach(c -> {
                    String simpleName = c.getSimpleName();
                    String className = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1, simpleName.length());
                    Method[] methods = c.getMethods();
                    if (Objs.isEmpty(methods)) {
                        return;
                    }

                    Arrays.stream(methods)
                            .filter(this::isServiceInterface)
                            .forEach(method -> {
                                String methodName = method.getName();
                                methodName = methodName.substring(0, 1) + methodName.substring(1, methodName.length() - 1);
                                services.add(className + SERVICE_NAME_SEPARATOR + methodName);
                            });

                });

    }

    public List<String> getServices() {
        if (Objs.isEmpty(services)) setLocalService();
        return services;
    }

    public static void main(String[] args) {
        String str = "DemoController";
        System.out.println(str.substring(0, 1).toLowerCase() + str.substring(1, str.length()));
        System.out.println(str.length());
    }

    /**
     * 是否服务类
     *
     * @param c 类
     * @return boolean
     */
    private boolean isServiceController(Class<?> c) {
        return Objs.nonEmpty(c.getAnnotation(Controller.class)) || Objs.nonEmpty(c.getAnnotation(RestController.class));
    }

    /**
     * 是否服务接口
     *
     * @param method 方法
     * @return boolean
     */
    private boolean isServiceInterface(Method method) {
        return Objs.nonEmpty(method.getAnnotation(GetMapping.class)) ||
                Objs.nonEmpty(method.getAnnotation(DeleteMapping.class)) ||
                Objs.nonEmpty(method.getAnnotation(PostMapping.class)) ||
                Objs.nonEmpty(method.getAnnotation(PutMapping.class)) ||
                Objs.nonEmpty(method.getAnnotation(RequestMapping.class));
    }


}
